use mlua::{UserData, UserDataMethods};
use crate::models::crypto::aead::{aes_ecb_encode, aes_ecb_decode, aes_cbc_encode, aes_cbc_decode};

#[derive(Default)]
pub struct AES {
    key_size:String,
    key:String,
    iv:String,
    err:String,
    dec:Vec<u8>,
}
impl AES{
    pub fn new(key_size:String)->Self{
        AES{key_size,
        key:String::default(),
        iv:String::default(),
            err:String::new(),
            dec:vec![]
        }
    }
    fn code(&mut self,res:std::result::Result<Vec<u8>,String>)->mlua::Result<bool>{
        match res{
            Err(e)=>{
                self.err = e;Ok(false)
            }
            Ok(o)=>{
                self.dec = o;Ok(true)
            }
        }
    }
}

impl UserData for AES{
    fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
        methods.add_method_mut("set_size",|_,aes,m:String|{
            aes.key_size = m;
            Ok(())
        });
        methods.add_method_mut("set_key",|_,aes,m:String|{
            // wd_log::log_debug_ln!("key[\"{}\"] len:{} byte_len {}",&m,m.len(),m.bytes().len());
            aes.key = m;
            Ok(())
        });
        methods.add_method_mut("set_iv",|_,aes,m:String|{
            aes.iv = m;
            Ok(())
        });
        methods.add_method("error",|_,aes,()|{
            Ok(aes.err.clone())
        });
        methods.add_method("output",|_,aes,()|{
            Ok(aes.dec.clone())
        });
        methods.add_method_mut("ecb_encode",|_,aes,src:Vec<u8>|{
            let res =  aes_ecb_encode(aes.key_size.as_str(),aes.key.as_bytes(),src.as_slice());
            aes.code(res)
        });
        methods.add_method_mut("ecb_decode",|_,aes,src:Vec<u8>|{
            let res =  aes_ecb_decode(aes.key_size.as_str(),aes.key.as_bytes(),src.as_slice());
            aes.code(res)
        });
        methods.add_method_mut("cbc_encode",|_,aes,src:Vec<u8>|{
            // wd_log::log_debug_ln!("size:{} key:{} iv:{} src:{}",aes.key_size.to_string(),aes.key.to_string(),aes.iv.to_string(),src.clone().as_str());
            let res =  aes_cbc_encode(aes.key_size.as_str(),aes.key.as_bytes(),aes.iv.as_bytes(),src.as_slice());
            aes.code(res)
        });
        methods.add_method_mut("cbc_decode",|_,aes,src:Vec<u8>|{
            // wd_log::log_debug_ln!("size:{} key:{} iv:{} ",aes.key_size.to_string(),aes.key.to_string(),aes.iv.to_string());
            let res =  aes_cbc_decode(aes.key_size.as_str(),aes.key.as_bytes(),aes.iv.as_bytes(),src.as_slice());
            aes.code(res)
        });

    }
}